/**
 * Wuhan University Library for Cryptography (WULC) is an ongoing and portable 
 * cryptographic toolkit developed by Cryptography and Blockchain Technology
 * Laboratory · Wuhan University. 
 * This file is part of WULC. 
 * @copyright Copyright (c) 2018-2023 WULC authors
 * 
 * @file server.java
 * @brief to descirbe server actions
 * 
 * @author Qiao Hongyi (974446987@qq.com)
 * @version 0.1.1
 * @date 2023-01-16
 * 
 * @ingroup {group}
 */
package com.cspemks;

import it.unisa.dia.gas.jpbc.Field;
import it.unisa.dia.gas.jpbc.Pairing;
import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

/**
 * 服务端
 *
 * @author 凌风
 */
public class server extends Thread {
    /*
     * java.net.ServerSocket
     * 运行在服务端的ServerSocket主要有两个作用
     * 1:向系统申请服务端口，客户端就是通过这个端口与服务端建立连接的。
     *
     * 2:监听该端口，这样一旦一个客户端通过该端口尝试建立连接时，ServerSocket就会自动实例化
     *   一个Socket，那么通过这个Socket就可以与客户端对等并进行数据交互了。
     */
    ServerSocket server;
    Socket socket;

    public server() {
        try {
            /*
             * 实例化ServerSocket的同时要向系统
             * 申请服务端口，客户端就是通过这个端
             * 口与服务端建立连接的。
             */
            System.out.println("正在启动服务端...");
            server = new ServerSocket(8080);
            System.out.println("服务端启动完毕!");

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    public void run() {
        super.run();
        try {
            /*
             * Socket accept()
             * ServerSocket的accept方法是一个阻塞
             * 方法，调用后会一直等待，直到一个客户端
             * 建立连接为止，此时该方法会返回一个Socket
             * 实例，通过这个Socket就可以与刚连接上的
             * 客户端进行数据交互了。
             * 多次调用accept可以等待不同客户端的连接
             */
            while (true) {
                System.out.println("等待客户端连接...");
                socket = server.accept();
                System.out.println("一个客户端连接了!");

                //连接并返回socket后，再启用发送消息线程
                new sendThread().start();

                /*
                 * 通过Socket获取输入流，可以读取到远端
                 * 计算机发送过来的字节。
                 */
                InputStream in = socket.getInputStream();
                InputStreamReader isr = new InputStreamReader(in, "UTF-8");
                BufferedReader br = new BufferedReader(isr);

                String line = null;
                while ((line = br.readLine()) != null) {
                    System.out.println("客户端说:" + line);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    class sendThread extends Thread {

        @Override
        public void run() {
            super.run();

            try {
                if (socket != null) {
                    Scanner scanner = new Scanner(System.in);
                    OutputStream out = socket.getOutputStream();
                    OutputStreamWriter osw;
                    BufferedWriter bw;
                    PrintWriter pw;
                    do {
                        osw = new OutputStreamWriter(out, "UTF-8");
                        bw = new BufferedWriter(osw);
                        pw = new PrintWriter(bw, true);
                        String line = scanner.nextLine();
                        pw.println(line);
                    } while (true);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Pairing bp = PairingFactory.getPairing("a.properties");

        server server = new server();
        server.start();
    }
}
